﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Unit.cs" company="Marcelo Roca">
//   Copyright (c) 2011 Marcelo Roca. All rights reserved.
// </copyright>
// <author name="Marcelo Roca" email="marce@marceloroca.com"/>
// <license>
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
// 
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program.  If not, see http://www.gnu.org/licenses/.
// </license>
// --------------------------------------------------------------------------------------------------------------------

namespace GameKits.Unity.Rts
{
    using System.Collections.Generic;
    using UnitComponents;
    using UnityEngine;

    public abstract class UnitBase
    {
        /// <summary>
        /// lista de componentes que tiene la unidad
        /// </summary>
        private readonly HashSet<UnitComponent> unitComponents = new HashSet<UnitComponent>();

        /// <summary>
        /// La salud de la unidad
        /// </summary>
        private float healt = 1;

        /// <summary>
        /// Gets or sets Healt.
        /// </summary>
        ///  /// <remarks>
        /// El valor puede ser solo entre 0 y 1
        /// </remarks>
        public float Healt
        {
            get { return this.healt; }
            set { this.healt = Mathf.Clamp01(value); }
        }

        /// <summary>
        /// Gets or sets a value indicating whether IsShowGuizmos.
        /// </summary>
        public bool IsShowGuizmos
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets a value indicating whether IsEnabled.
        /// </summary>
        public bool IsEnabled
        {
            get;
            set;
        }

        /// <summary>
        /// Gets GameObject.
        /// </summary>
        public GameObject GameObject
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets Transform.
        /// </summary>
        public Transform Transform
        {
            get;
            private set;
        }

        /// <summary>
        /// Adicionamos un componente a la unidad
        /// </summary>
        /// <typeparam name="T">
        /// El tipo de componente a crear
        /// </typeparam>
        /// <returns>
        /// El componente creado
        /// </returns>
        public T AddComponent<T>() where T : UnitComponent, new()
        {
            var c = new T();
            this.unitComponents.Add(c);
            return c;
        }

        /// <summary>
        /// Implementamos MonoBehaviour.Update
        /// </summary>
        /// <param name="deltaTime">
        /// The delta Time.
        /// </param>
        public void Update(float deltaTime)
        {
            if (!this.IsEnabled)
            {
                return;
            }

            foreach (var component in this.unitComponents)
            {
                component.Update(deltaTime);
            }
        }

        /// <summary>
        /// Implements MonoBehaviour.OnShowGizmos
        /// </summary>
        public void ShowGizmos()
        {
            if (!this.IsShowGuizmos)
            {
                return;
            }

            foreach (var component in this.unitComponents)
            {
                component.ShowGizmos();
            }
        }

        /// <summary>
        /// REaliza la inicialización de la unidad
        /// </summary>
        /// <param name="transform">
        /// The transform.
        /// </param>
        /// <param name="gameObject">
        /// The game Object.
        /// </param>
        public void Initialize(Transform transform, GameObject gameObject)
        {
            this.Transform = transform;
            this.GameObject = gameObject;

            this.InitializeUnit();

            foreach (var component in this.unitComponents)
            {
                component.Initialize(this);
            }
        }

        /// <summary>
        /// Realizamos la inicialización de la unidad
        /// </summary>
        public abstract void InitializeUnit();
    }
}
